<template>
<div v-if="showPopup" class="small-popup" @touchmove.stop.prevent="clear">
    <small-transition :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
    <small-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
        <div class="small-popup__wrapper-box" @click.stop="clear">
            <slot />
        </div>
    </small-transition>
</div>
</template>

<script>
import smallTransition from '@/components/smallTransition/index.vue'

/**
	 * PopUp 弹出层
	 * @description 弹出层组件，为了解决遮罩弹层的问题
	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
	 * @property {String} type = [top|center|bottom] 弹出方式
	 * 	@value top 顶部弹出
	 * 	@value center 中间弹出
	 * 	@value bottom 底部弹出
	 * @property {Boolean} animation = [ture|false] 是否开启动画
	 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
	 * @event {Function} change 打开关闭弹窗触发，e={show: false}
	 */
import Vue from 'vue'
export default Vue.extend({
  name: 'UniPopup',
  components: {
    smallTransition
  },
  props: {
    // 开启动画
    animation: {
      type: Boolean,
      default: true
    },
    // 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
    type: {
      type: String,
      default: 'center'
    },
    // maskClick
    maskClick: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      duration: 300,
      ani: [],
      showPopup: false,
      showTrans: false,
      maskClass: {
        position: 'fixed',
        bottom: 0,
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: 'rgba(0, 0, 0, 0.4)'
      },
      transClass: {
        position: 'fixed',
        left: 0,
        right: 0,
      }
    }
  },
  watch: {
    type: {
      handler(newVal) {
        switch (this.type) {
          case 'top':
            this.ani = ['slide-top']
            this.transClass = {
              position: 'fixed',
              left: 0,
              right: 0,
            }
            break
          case 'bottom':
            this.ani = ['slide-bottom']
            this.transClass = {
              position: 'fixed',
              left: 0,
              right: 0,
              bottom: 0
            }
            break
          case 'center':
            this.ani = ['zoom-out', 'fade']
            this.transClass = {
              position: 'fixed',
              /* #ifndef APP-NVUE */
              display: 'flex',
              flexDirection: 'column',
              /* #endif */
              bottom: 0,
              left: 0,
              right: 0,
              top: 0,
              justifyContent: 'center',
              alignItems: 'center'
            }
            break
          default:
            break
        }
      },
      immediate: true
    }
  },
  created() {
    if (this.animation) {
      this.duration = 300
    } else {
      this.duration = 0
    }
  },
  methods: {
    clear(e) {
      // TODO nvue 取消冒泡
      e.stopPropagation()
    },
    open() {
      this.showPopup = true
      this.$nextTick(() => {
        clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          this.showTrans = true
        }, 50)
      })
      this.$emit('change', {
        show: true
      })
    },
    close(type) {
      this.showTrans = false
      this.$nextTick(() => {
        clearTimeout(this.timer)
        this.timer = setTimeout(() => {
          this.$emit('change', {
            show: false
          })
          this.showPopup = false
        }, 300)
      })
    },
    onTap() {
      if (!this.maskClick) return
      this.close()
    }
  }
})
</script>
<style lang="scss">
    .small-popup {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 999999;
        .small-popup__mask {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            background-color: #fff;
            opacity: 0;
        }

        .mask-ani {
            transition-property: opacity;
            transition-duration: 0.2s;
        }

        .small-top-mask {
            opacity: 1;
        }

        .small-bottom-mask {
            opacity: 1;
        }

        .small-center-mask {
            opacity: 1;
        }

        .small-popup__wrapper {
            display: block;
            position: absolute;
        }

        .top {
            top: 0;
            left: 0;
            right: 0;
            transform: translateY(-500px);
        }

        .bottom {
            bottom: 0;
            left: 0;
            right: 0;
            transform: translateY(500px);
        }

        .center {
            display: flex;
            flex-direction: column;
            bottom: 0;
            left: 0;
            right: 0;
            top: 0;
            justify-content: center;
            align-items: center;
            transform: scale(1.2);
            opacity: 0;
        }

        .small-popup__wrapper-box {
            display: block;
            position: relative;
            background-color: #fff;
            border-radius:20px 20px 0 0;
        }

        .content-ani {
            // transition: transform 0.3s;
            transition-property: transform, opacity;
            transition-duration: 0.2s;
        }


        .small-top-content {
            transform: translateY(0);
        }

        .small-bottom-content {
            transform: translateY(0);
        }

        .small-center-content {
            transform: scale(1);
            opacity: 1;
        }
    }
</style>
